﻿package com.pandemicode.framework.utils {
	/**
	* @author Michael Lawrence
	* @version 1.0.0
	*/
	public class E4X {
		/**
		 * A collection of utilities for dealing with XML and XMLList objects.
		 */
		public function E4X() { }
		
		/**
		 * Retrieves unique XML nodes based on the attribute specified.
		 * @param	xml				The XMLList to search.
		 * @param	attributeName	The name of the attribute to use as a unique identifier.
		 * @return	Returns an XMLList of XML nodes that are unique based on the attribute specified.
		 */
		public static function getUniqueElementsFromAttributes(xml:XMLList, attributeName:String):XMLList {
			var a:Array = new Array();
			var av:String;
			return xml.(
				av = @[attributeName],
				a.indexOf(av) == -1 ? a.push(av) : null
			);
		}
		
		/**
		 * Retrieves unique attibute values based on a specific attribute name.
		 * @param	xml				The XMLList to search.
		 * @param	attributeName	The name of the attribute to use as a unique identifier.
		 * @return Returns unique attibute values based on a specific attribute name.
		 */
		public static function getUniqueAttributes(xml:XMLList, attributeName:String ):Array {
			return getUniqueElementsFromAttributes(xml, attributeName).@[attributeName].toXMLString().split("\n");
		}
		
		/**
		 * Sorts an XMLList based on an attribute.
		 * @param	list			The XMLList to sort.
		 * @param	attributeName	The attribute name to sort on.
		 * @return	An XMLList that has been sorted on the attribute specified.
		 */
		public static function sortXMLListByAttribute(list:XMLList, attributeName:String):XMLList {
			var sorted:XMLList = new XMLList();
			var a:Array = getUniqueAttributes(list, attributeName);
			for each(var s:String in a)
				sorted += list.(s == @[attributeName]);
			return sorted;
		}
		
		/**
		 * Retrieves unique XML nodes sorted based on the attribute specified.
		 * @param	xml				The XMLList to sort.
		 * @param	attributeName	The name of the attribute to use as a unique identifier and to sort by.
		 * @return	Returns unique XML nodes sorted based on the attribute specified.
		 */
		public static function getUniqueElementsFromAttributesSorted(xml:XMLList, attributeName:String):XMLList {
			return sortXMLListByAttribute(getUniqueElementsFromAttributes(xml, attributeName), attributeName);
		}
		
		/**
		 * Retrieves unique attibute values based on a specific attribute name and specified element type.
		 * @param	xml				The XMLList to sort.
		 * @param	elementName		The element type to retrieve.
		 * @param	attributeName	The name of the attribute to use as a unique identifier;
		 * @return	Returns unique attibute values based on a specific attribute name and specified element type.
		 */
		public static function getUniqueElementAttributeOfAllDescendants(xml:XMLList, elementName:String, attributeName:String ):Array {
			return getUniqueElementsFromAttributeOfAllDescendants(xml, elementName, attributeName).@[attributeName].toXMLString().split("\n");
		}
		
		/**
		 * Retrieves unique XML nodes of all descendants based on the attribute specified and element specified.
		 * @param	xml				The XMLList to sort.
		 * @param	elementName		The element type to retrieve.
		 * @param	attributeName	The name of the attribute to use as a unique identifier.
		 * @return	Returns unique XML nodes of all descendants based on the attribute specified and element specified.
		 */
		public static function getUniqueElementsFromAttributeOfAllDescendants(xml:XMLList, elementName:String, attributeName:String):XMLList {
			return getUniqueElementsFromAttributes(xml[elementName], attributeName);
		}
		
		/**
		 * Retrieves unique XML nodes of all descendants based on the attribute specified and element specified sorted.
		 * @param	xml				The XMLList to sort.
		 * @param	elementName		The element type to retrieve.
		 * @param	attributeName	The name of the attribute to use as a unique identifier and to sort by.
		 * @return	Returns unique XML nodes of all descendants based on the attribute specified and element specified sorted.
		 */
		public static function getUniqueElementsFromAttributeOfAllDescendantsSorted(xml:XMLList, elementName:String, attributeName:String):XMLList {
			return sortXMLListByAttribute(getUniqueElementsFromAttributeOfAllDescendants(xml, elementName, attributeName), attributeName);
		}
	}
}